<?php

namespace Plugin\PaypalSiteA\Services;


use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Matrix\Exception;
use Plugin\PaypalSiteA\Models\PollingSiteIndex;
use Plugin\PaypalSiteA\Models\PollingSiteOrders;

class PaypalSiteTools
{
    //根据onrderNo获取当前应该使用哪个配置
    public function getPollingSetting($orderNo, $payment_code = 'paypal_site_a')
    {
        $pollingSiteOrder = PollingSiteOrders::query()->where("order_no", $orderNo)->where("payment_code", $payment_code)->first();

        if ($pollingSiteOrder) {//已经初始化过该订单
            $domain = $pollingSiteOrder->domain;
        } else {
            $settings    = null;
            $allSettings = plugin_setting($payment_code . '.setting', []);
            if (empty($allSettings)) {
                return null;
            }
            DB::beginTransaction();
            try {

                $usedWeight = false;
                $tmpWeight  = null;
                $weights    = [];
                foreach ($allSettings as $key => $setting) {
                    if ($setting['status'] == 1) {
                        $weight        = isset($setting['weight']) ? $setting['weight'] : 0;
                        $weights[$key] = $weight;
                        if ($tmpWeight == null) {
                            $tmpWeight = $weight;
                        } else if ($tmpWeight != $weight) {//存在不一样的权重值，说明是按权重了
                            $usedWeight = true;
                        }
                    }
                }
                $ppIndex = null;
                $index   = null;
                if ($usedWeight) {
                    $index = $this->weightedRandom($weights);
                    $index = $index - 1;
                } else {
                    $ppIndex = PollingSiteIndex::query()->where("payment_code", $payment_code)->first();
                    if ($ppIndex) {
                        $index = $ppIndex->now_index + 1;
                    }
                }


                if ($index != null) {
                    foreach ($allSettings as $key => $setting) {
                        if ($key >= $index && $setting['status'] == 1) {
                            $settings = $setting;
                            break;
                        }
                    }
                    if ($settings == null) {
                        foreach ($allSettings as $key => $setting) {
                            if ($setting['status'] == 1) {
                                $settings = $setting;
                                $index    = $key;
                                break;
                            }
                        }
                    }
                    if ($settings == null) {
                        DB::rollBack();
                        return null;
                    }

                    $domain = $settings['domain'];
                    if (!$usedWeight) {
                        $ppIndex->now_index  = $index;
                        $ppIndex->updated_at = Carbon::now()->toDateTimeString();
                        $ppIndex->update();
                    }
                } else {
                    foreach ($allSettings as $key => $setting) {
                        if ($setting['status'] == 1) {
                            $settings = $setting;
                            $index    = $key;
                            break;
                        }
                    }
                    if ($settings == null) {
                        DB::rollBack();
                        return null;
                    }
                    $domain = $settings['domain'];
                    if (!$usedWeight) {
                        $indeData = [
                            'payment_code' => $payment_code,
                            'now_index'    => $index,
                            'domain'       => $domain,
                            'created_at'   => Carbon::now()->toDateTimeString(),
                            'updated_at'   => Carbon::now()->toDateTimeString()
                        ];
                        PollingSiteIndex::query()->insert($indeData);
                    }
                }


                $pData = [
                    'payment_code' => $payment_code,
                    'order_no'     => $orderNo,
                    'domain'       => $domain,
                    'created_at'   => Carbon::now()->toDateTimeString(),
                    'updated_at'   => Carbon::now()->toDateTimeString()
                ];
                PollingSiteOrders::query()->insert($pData);

                DB::commit();

            } catch (\Exception $exception) {
                Log::debug($exception);
                DB::rollBack();
            }
        }
        return $domain;
    }

    /**
     * 根据权重占比的随机函数
     *
     * @param array $weights 权重数组，键为选项，值为该选项的权重
     * @return string|int 返回被选中的键（选项）
     */
    private function weightedRandom(array $weights)
    {
        // 计算权重总和
        $totalWeight = array_sum($weights);

        if ($totalWeight <= 0) {
            throw new Exception("权重总和必须大于0");
        }

        // 生成一个 [0, 总权重) 范围内的随机数
        $random = mt_rand(1, $totalWeight);

        // 遍历权重数组，找到随机数对应的选项

        foreach ($weights as $key => $weight) {
            $random -= $weight;
            if ($random <= 0) {
                return $key;
            }
        }

        // 理论上不会到达这里
        throw new Exception("随机选择失败，请检查权重数组");
    }

    public function httpPost($token, $domain, $method, $data_string)
    {

        //对数据加密
        $time     = time();
        $key      = md5($time . $token . $time);
        $aesTools = new AesTools($key);
        $data     = $aesTools->encrypt($data_string);
        $postData = [
            'time' => $time,
            'data' => $data
        ];
        $postData = json_encode($postData, true);
        $headers  = [
            "Content-Type: application/json; charset=utf-8",
            "Content-Length: " . strlen($postData),
        ];

        //Log::debug($domain . $method);
        $ci = curl_init();
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ci, CURLOPT_ENCODING, "");
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ci, CURLOPT_HEADER, FALSE);
        curl_setopt($ci, CURLOPT_POST, TRUE);
        curl_setopt($ci, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ci, CURLOPT_URL, $domain . $method);
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
        curl_setopt($ci, CURLOPT_USERAGENT, request()->userAgent()); // 设置UserAgent

        $response = curl_exec($ci);
        curl_close($ci);

        return $response;
    }
}
